package net.lab1024.sa.admin.module.business.expression.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jakarta.validation.Valid;
import net.lab1024.sa.admin.module.business.expression.dao.FuncExpressionDao;
import net.lab1024.sa.admin.module.business.expression.domain.entity.FuncExpressionEntity;
import net.lab1024.sa.admin.module.business.expression.domain.form.FuncExpressionAddForm;
import net.lab1024.sa.admin.module.business.expression.domain.form.FuncExpressionQueryForm;
import net.lab1024.sa.admin.module.business.expression.domain.form.FuncExpressionUpdateForm;
import net.lab1024.sa.admin.module.business.expression.domain.vo.FuncExpressionCalculateVO;
import net.lab1024.sa.admin.module.business.expression.domain.vo.FuncExpressionVO;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.MapContext;
import org.jetbrains.annotations.NotNull;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;


/**
 * 函数表达式 Service
 *
 * @Author zzx
 * @Date 2025-08-05 10:54:11
 * @Copyright zzx
 */

@Service
public class FuncExpressionService {

    @Resource
    private FuncExpressionDao funcExpressionDao;
    @Resource
    private DataTracerService dataTracerService;

    /**
     * 分页查询
     */
    public PageResult<FuncExpressionVO> queryPage(FuncExpressionQueryForm queryForm) {
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        List<FuncExpressionVO> list = funcExpressionDao.queryPage(page, queryForm);
        return SmartPageUtil.convert2PageResult(page, list);
    }

    /**
     * 添加
     */
    public ResponseDTO<String> add(FuncExpressionAddForm addForm) {
        FuncExpressionEntity funcExpressionEntity = SmartBeanUtil.copy(addForm, FuncExpressionEntity.class);
        RequestUser user = SmartRequestUtil.getRequestUser();
        funcExpressionEntity.setCreateTime(LocalDateTime.now());
        funcExpressionEntity.setUpdateTime(LocalDateTime.now());
        funcExpressionEntity.setCreateUserId(user.getUserId());
        funcExpressionEntity.setCreateUserName(user.getUserName());
        funcExpressionEntity.setUpdateUserId(user.getUserId());
        funcExpressionDao.insert(funcExpressionEntity);
        dataTracerService.insert(funcExpressionEntity.getFuncId(), DataTracerTypeEnum.EXPRESSION);
        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     */
    public ResponseDTO<String> update(FuncExpressionUpdateForm updateForm) {
        FuncExpressionEntity newEntity = SmartBeanUtil.copy(updateForm, FuncExpressionEntity.class);
        FuncExpressionEntity originEntity = funcExpressionDao.selectById(updateForm.getFuncId());
        RequestUser user = SmartRequestUtil.getRequestUser();
        newEntity.setUpdateUserId(user.getUserId());
        funcExpressionDao.updateById(newEntity);
        dataTracerService.update(newEntity.getFuncId(), DataTracerTypeEnum.EXPRESSION, originEntity, newEntity);
        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     */
    public ResponseDTO<String> batchDelete(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)){
            return ResponseDTO.ok();
        }

        funcExpressionDao.batchUpdateDeleted(idList, true);

        return ResponseDTO.ok();
    }

    /**
     * 单个删除
     */
    public ResponseDTO<String> delete(Long funcId) {
        if (null == funcId){
            return ResponseDTO.ok();
        }

        funcExpressionDao.updateDeleted(funcId, true);
        dataTracerService.batchDelete(Collections.singletonList(funcId), DataTracerTypeEnum.EXPRESSION);
        return ResponseDTO.ok();
    }

    /**
     * 查询全部 - 转换为FuncExpressionCalculateVO
     * @param form
     * @return
     */
    public List<FuncExpressionCalculateVO> queryAll(@Valid FuncExpressionQueryForm form) {
        List<FuncExpressionVO> list = funcExpressionDao.queryAll(form);
        List<FuncExpressionCalculateVO> resultList = new ArrayList<>();
        list.forEach(item -> {
            FuncExpressionCalculateVO result = SmartBeanUtil.copy(item, FuncExpressionCalculateVO.class);
            List<FuncExpressionCalculateVO.CalculateVO> innerList = getCalculateVOList(result);
            result.setList(innerList);
            resultList.add(result);
        });
        return resultList;
    }

    @NotNull
    private static List<FuncExpressionCalculateVO.CalculateVO> getCalculateVOList(FuncExpressionCalculateVO expressionCalculateVO) {
        HashMap<String,String> map = new HashMap<>();
        if (expressionCalculateVO.getRemark() != null) {
            String[] split = expressionCalculateVO.getRemark().split(",");
            for (int i = 0; i < split.length; i++) {
                String[] dess = split[i].split(":");
                if (dess.length == 2) {
                    map.put(dess[0].trim(), dess[1]);
                }
            }
        }
        // 匹配一个或多个字母数字字符
        Pattern pattern = Pattern.compile("[a-zA-Z]+");
        Matcher matcher = pattern.matcher(expressionCalculateVO.getFuncExpression());
        List<FuncExpressionCalculateVO.CalculateVO> innerList = new ArrayList<>();

        String keys = "";
        while (matcher.find()) {
            String key = matcher.group();
            if (!keys.contains(key)) {
                FuncExpressionCalculateVO.CalculateVO vo = new FuncExpressionCalculateVO.CalculateVO();
                vo.setFuncKey(key);
                vo.setFuncDes(map.getOrDefault(key, ""));
                innerList.add(vo);
                keys = keys + "," + key;
            }
        }
        return innerList;
    }

    /**
     * 计算表达式
     * @param form
     * @return
     */
    public Double calculateData(@Valid FuncExpressionCalculateVO form) {
        // 创建Jexl引擎实例
        JexlEngine jexl = new JexlBuilder().create();
        // 创建上下文环境并添加变量
        Map<String, Object> vars = new HashMap<>();
        form.getList().forEach(item -> {
            vars.put(item.getFuncKey(), item.getFuncValue());
        });
        JexlContext context = new MapContext(vars);
        Double result = (Double) jexl.createExpression(form.getFuncExpression()).evaluate(context);
        BigDecimal bd = new BigDecimal(result.toString());
        return bd.setScale(6, RoundingMode.HALF_UP).doubleValue();
    }
}
